JavaScript
part 15/19 Β· 71.4 KB total
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Une fermeture lexicale (lexical closure en anglais) est une fonction accompagnΓ©e de son environnement lexical externe, c'est-Γ -dire de l'ensemble des variables non locales qu'elle a capturΓ©, soit par valeur (conservation d'une copie de chaque donnΓ©e liΓ©e aux variables non locales), soit par rΓ©fΓ©rence (conservation d'une rΓ©fΓ©rence Γ chaque donnΓ©e liΓ©e aux variables non locales). Comme en JavaScript toutes les variables sont de type rΓ©fΓ©rence (cf. la section Liaison des identifiants), JavaScript n'utilise que la capture par rΓ©fΓ©rence β ce qui correspond en C++ 11 Γ la syntaxe [&](β¦) { β¦ }; β, et la durΓ©e de vie des variables non locales capturΓ©es par une fonction est Γ©tendue Γ la durΓ©e de vie de la fonction β ce qui n'est pas le cas en C++ 11, quel que soit le type de capture :
function maFonction() {
var maVariable = 4; // variable parente
return function () {
alert(maVariable);
}
}
var maFermeture = maFonction(); // capture de la variable parente par rΓ©fΓ©rence
maFermeture(); // affiche 4
Expressions de fonctions immΓ©diatement invoquΓ©es
Jusqu'à ECMAScript 6, JavaScript ne proposait pas nativement de portée des variables au niveau des blocs (pas de mots-clé let ou const), ni de modules. Pour éviter de polluer l'espace global, une méthode consistait à encapsuler son code dans une fonction pour s'appuyer sur la portée des variables qui a lieu au niveau des fonctions en JavaScript, puis à invoquer cette fonction juste après. Pour regrouper les deux étapes (définition de la fonction et invocation) et ne pas ajouter un nom de fonction supplémentaire dans l'espace global, le langage permet les expressions de fonctions immédiatement invoquées (EFII ; en anglais immediately-invoked function expressions, IIFE)cite-ref-30[30].
Plusieurs syntaxes sont possibles pour ce type d'expression, les plus rΓ©pandues Γ©tant :
β’ (function (β¦) { β¦ }(β¦)); (syntaxe recommandΓ©e par Douglas Crockford pour sa lisibilitΓ©)cite-ref-31[31] ;
β’ (function (β¦) { β¦ })(β¦);
L'opérateur d'invocation de fonction () à la fin permet l'exécution immédiate de la fonction. Les parenthèses en gras indiquent à l'analyseur syntaxique qu'elles contiennent une expression, car en JavaScript les parenthèses ne peuvent pas contenir de déclaration. Autrement, dans la plupart des situations, le mot clé function est traité comme une déclaration de fonction, et pas comme une expression de fonction. Il existe d'autres façons pour forcer une expression de fonction :
β’ !function (β¦) { β¦ }(β¦);
β’ ~function (β¦) { β¦ }(β¦);
β’ -function (β¦) { β¦ }(β¦);
β’ +function (β¦) { β¦ }(β¦);
Dans les contextes où une expression est attendue il n'est pas nécessaire d'utiliser les parenthèses en gras :
β’ var maVariable = function (β¦) { β¦ }(β¦);
β’ true && function (β¦) { β¦ }(β¦);
β’ 0, function (β¦) { β¦ }(β¦);
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ